#ifndef SRC_CLIENT_SIMULATOR_RTSP_CLIENT_H_
#define SRC_CLIENT_SIMULATOR_RTSP_CLIENT_H_

#include "base/sigslot.h"
#include "base/event_loop.h"
#include "base/async_socket.h"

class RtspClient : public noncopyable,
  public std::enable_shared_from_this<RtspClient>,
  public sigslot::has_slots<> {
 public:
  typedef std::shared_ptr<RtspClient> Ptr;
  RtspClient(EventLoop::Ptr event_loop, const std::string &sn);
  virtual ~RtspClient();

 public:
  sigslot::signal0<> SignalHello;
  sigslot::signal1<RtspClient::Ptr> SignalClosed;

 public:
  std::string sn() const {
    return sn_;
  }
  bool Start(const std::string &ip, int port);

  void Play(int duration_seconds);
  void OnCloseTimer();

  bool Save(const char* path);

 private:
  void OnAsyncSocketConnected(AsyncSocket::Ptr async_socket);
  void OnAsyncSocketPacket(AsyncSocket::Ptr async_socket,
                           uint16_t cmd,
                           const char *data,
                           uint32_t data_size);
  void OnAsyncSocketError(AsyncSocket::Ptr async_socket, int error_code);
  void OnAsyncSocketClosed(AsyncSocket::Ptr async_socket);

  struct timeval CalculateDelay(struct timeval &during_tv);

 private:
  EventLoop::Ptr event_loop_;
  std::string sn_;
  AsyncSocket::Ptr async_socket_;
  struct event *close_evtimer_;
  struct timeval base_tv_;
  int64_t base_delay_usec_;
  std::list<int64_t> delays_;
};

#endif  // SRC_CLIENT_SIMULATOR_RTSP_CLIENT_H_
